/*
Copyright [2020] [https://www.xiaonuo.vip]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：

1.请不要删除和修改根目录下的LICENSE文件。
2.请不要删除和修改Snowy源码头部的版权声明。
3.请保留源码和相关描述文件的项目出处，作者声明等。
4.分发源码时候，请注明软件出处 https://gitee.com/xiaonuobase/snowy
5.在修改包名，模块名称，项目代码等时，请注明软件出处 https://gitee.com/xiaonuobase/snowy
6.若您的项目无法满足以上几点，可申请商业授权，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.modular.manage.biindextype.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import vip.xiaonuo.core.dbs.CurrentDataSourceContext;
import vip.xiaonuo.core.exception.ServiceException;
import vip.xiaonuo.core.factory.PageFactory;
import vip.xiaonuo.core.factory.TreeBuildFactory;
import vip.xiaonuo.core.pojo.page.PageResult;
import vip.xiaonuo.core.util.PoiUtil;
import vip.xiaonuo.modular.common.WdAnalysisConst;
import vip.xiaonuo.modular.manage.biindexdata.mapper.BiIndexDataMapper;
import vip.xiaonuo.modular.manage.biindexdata.param.BiIndexDataParam;
import vip.xiaonuo.modular.manage.biindexdatasum.entity.BiIndexDataSum;
import vip.xiaonuo.modular.manage.biindextype.entity.BiIndexType;
import vip.xiaonuo.modular.manage.biindextype.enums.BiIndexTypeExceptionEnum;
import vip.xiaonuo.modular.manage.biindextype.mapper.NewBiIndexTypeMapper;
import vip.xiaonuo.modular.manage.biindextype.node.TypeBaseTreeNode;
import vip.xiaonuo.modular.manage.biindextype.param.BiIndexTypeParam;
import vip.xiaonuo.modular.manage.biindextype.service.BiIndexTypeService;

import javax.annotation.Resource;
import java.io.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 指标分类service接口实现类
 *
 * @author cy
 * @date 2022-07-28 19:18:50
 */
@Service("newIndexTypeServiceImpl")
public class BiIndexTypeServiceImpl extends ServiceImpl<NewBiIndexTypeMapper, BiIndexType> implements BiIndexTypeService {

    @Resource
    private BiIndexDataMapper biIndexDataMapper;

    @Override
    public PageResult<BiIndexType> page(BiIndexTypeParam biIndexTypeParam) {
        QueryWrapper<BiIndexType> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotNull(biIndexTypeParam)) {

            // 根据指标名称 查询
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getName())) {
                queryWrapper.lambda().eq(BiIndexType::getName, biIndexTypeParam.getName());
            }
            // 根据 查询
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getCode())) {
                queryWrapper.lambda().eq(BiIndexType::getCode, biIndexTypeParam.getCode());
            }
            // 根据指标级别 查询
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getLevel())) {
                queryWrapper.lambda().eq(BiIndexType::getLevel, biIndexTypeParam.getLevel());
            }
            // 根据指标类型 查询
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getType())) {
                queryWrapper.lambda().eq(BiIndexType::getType, biIndexTypeParam.getType());
            }
            // 根据排序 查询
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getOrderList())) {
                queryWrapper.lambda().eq(BiIndexType::getOrderList, biIndexTypeParam.getOrderList());
            }
            // 根据父id 查询
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getPid())) {
                queryWrapper.lambda().eq(BiIndexType::getPid, biIndexTypeParam.getPid());
            }
            // 根据 查询
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getPids())) {
                queryWrapper.lambda().eq(BiIndexType::getPids, biIndexTypeParam.getPids());
            }
            // 根据是否父分组 Y/N 查询
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getIsParent())) {
                queryWrapper.lambda().eq(BiIndexType::getIsParent, biIndexTypeParam.getIsParent());
            }
            // 根据是否默认指标 Y/N 查询
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getIsDefault())) {
                queryWrapper.lambda().eq(BiIndexType::getIsDefault, biIndexTypeParam.getIsDefault());
            }
            // 根据是否启用 Y/N 查询
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getIsEnable())) {
                queryWrapper.lambda().eq(BiIndexType::getIsEnable, biIndexTypeParam.getIsEnable());
            }
            // 根据说明 查询
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getDescription())) {
                queryWrapper.lambda().eq(BiIndexType::getDescription, biIndexTypeParam.getDescription());
            }
            // 根据指标图样地址 查询
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getImageUrl())) {
                queryWrapper.lambda().eq(BiIndexType::getImageUrl, biIndexTypeParam.getImageUrl());
            }
            // 根据 查询
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getSource())) {
                queryWrapper.lambda().eq(BiIndexType::getSource, biIndexTypeParam.getSource());
            }
        }
        return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper));
    }

    @Override
    public List<BiIndexType> list(BiIndexTypeParam biIndexTypeParam) {
        return this.list();
    }

    @Override
    public boolean add(BiIndexTypeParam biIndexTypeParam) {
        QueryWrapper<BiIndexType> queryWrapperparam=new QueryWrapper<>();
        queryWrapperparam.lambda().eq(BiIndexType::getName,biIndexTypeParam.getName());
        BiIndexType biIndexTypeByName = this.getOne(queryWrapperparam);
        if (biIndexTypeByName == null){
            if (biIndexTypeParam.getPid() != 0){
                BiIndexType biIndexType = new BiIndexType();
                // 查询父pids
                if (ObjectUtil.isNotNull(biIndexTypeParam)){
                    // 根据pid 查询
                    if (ObjectUtil.isNotEmpty(biIndexTypeParam.getPid())) {
                        QueryWrapper<BiIndexType> queryWrapper =new QueryWrapper<>();
                        queryWrapper.lambda().eq(BiIndexType::getId, biIndexTypeParam.getPid());
                        BeanUtil.copyProperties(biIndexTypeParam, biIndexType);
                        BiIndexType ParentBiIndexType = this.getOne(queryWrapper);
                        biIndexType.setPids(ParentBiIndexType.getPids()+"["+biIndexType.getPid()+"]"+",");
                        if (biIndexTypeParam.getIsDefaultFT()){
                            biIndexType.setIsDefault("Y");
                        }else{
                            biIndexType.setIsDefault("N");
                        }
                        if (biIndexTypeParam.getIsCommonFT()){
                            biIndexType.setIsCommon("Y");
                        }else{
                            biIndexType.setIsCommon("N");
                        }
                        boolean save = this.save(biIndexType);
                        return save;
                    }
                }
            }else{
                BiIndexType biIndexType = new BiIndexType();
                BeanUtil.copyProperties(biIndexTypeParam, biIndexType);
                biIndexType.setPids("[0],");
                biIndexType.setIsParent("1");
                if (biIndexTypeParam.getIsDefaultFT()){
                    biIndexType.setIsDefault("Y");
                }else{
                    biIndexType.setIsDefault("N");
                }
                if (biIndexTypeParam.getIsCommonFT()){
                    biIndexType.setIsCommon("Y");
                }else{
                    biIndexType.setIsCommon("N");
                }
                boolean save = this.save(biIndexType);
                return save;
            }
        }
        return false;

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<BiIndexTypeParam> biIndexTypeParamList) {
        biIndexTypeParamList.forEach(biIndexTypeParam -> {
            this.removeById(biIndexTypeParam.getId());
        });
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean edit(BiIndexTypeParam biIndexTypeParam) {
            if (ObjectUtil.isNotNull(biIndexTypeParam)){
                if (biIndexTypeParam.getPid() != 0){
                    if (ObjectUtil.isNotEmpty(biIndexTypeParam.getPid())) {
                        // 查询父pids
                        // 根据pid 查询
                        QueryWrapper<BiIndexType> queryWrapper =new QueryWrapper<>();
                        queryWrapper.lambda().eq(BiIndexType::getId, biIndexTypeParam.getPid());
                        BiIndexType ParentBiIndexType = this.getOne(queryWrapper);

                        BiIndexType biIndexType = this.queryBiIndexType(biIndexTypeParam);
                        BeanUtil.copyProperties(biIndexTypeParam, biIndexType);
                        biIndexType.setPids(ParentBiIndexType.getPids()+"["+biIndexType.getPid()+"]"+",");
                        if (biIndexTypeParam.getIsDefaultFT()){
                            biIndexType.setIsDefault("Y");
                        }else{
                            biIndexType.setIsDefault("N");
                        }
                        if (biIndexTypeParam.getIsCommonFT()){
                            biIndexType.setIsCommon("Y");
                        }else{
                            biIndexType.setIsCommon("N");
                        }
                        boolean b = this.updateById(biIndexType);
                        return b;
                    }
                }else{
                    System.out.println(biIndexTypeParam);
                    BiIndexType biIndexType = new BiIndexType();
                    BeanUtil.copyProperties(biIndexTypeParam, biIndexType);
                    if (biIndexTypeParam.getIsDefaultFT()){
                        biIndexType.setIsDefault("Y");
                    }else{
                        biIndexType.setIsDefault("N");
                    }
                    if (biIndexTypeParam.getIsCommonFT()){
                        biIndexType.setIsCommon("Y");
                    }else{
                        biIndexType.setIsCommon("N");
                    }
                    boolean b = this.updateById(biIndexType);
                    return b;
                }
        }
        return false;
    }

    @Override
    public BiIndexType detail(BiIndexTypeParam biIndexTypeParam) {
        return this.queryBiIndexType(biIndexTypeParam);
    }

    /**
     * 获取指标分类
     *
     * @author cy
     * @date 2022-07-28 19:18:50
     */
    private BiIndexType queryBiIndexType(BiIndexTypeParam biIndexTypeParam) {
        BiIndexType biIndexType = this.getById(biIndexTypeParam.getId());
        if (ObjectUtil.isNull(biIndexType)) {
            throw new ServiceException(BiIndexTypeExceptionEnum.NOT_EXIST);
        }
        return biIndexType;
    }

    @Override
    public void export(BiIndexTypeParam biIndexTypeParam) {
        List<BiIndexType> list = new ArrayList<>();
        PoiUtil.exportExcelWithStream("模板.xls", BiIndexType.class, list);
    }

    @Override
    public List<BiIndexType> findByIds(List<Long> ids) {
        LambdaQueryWrapper<BiIndexType> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(BiIndexType::getId,ids);
        return this.getBaseMapper().selectList(wrapper);
    }

    @Override
    public List<BiIndexType> listTree(BiIndexTypeParam biIndexTypeParam) {
        QueryWrapper<BiIndexType> queryWrapper =new QueryWrapper<>();
        if (ObjectUtil.isNotNull(biIndexTypeParam)){
            // 根据指标名称 查询
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getName())) {
                queryWrapper.lambda().like(BiIndexType::getName, biIndexTypeParam.getName());
            }
            // 根据是否启用 Y/N 查询
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getIsEnable())) {
                queryWrapper.lambda().eq(BiIndexType::getIsEnable, biIndexTypeParam.getIsEnable());
            }
            // 根据是否为默认指标
            if (ObjectUtil.isNotEmpty(biIndexTypeParam.getIsDefault())) {
                queryWrapper.lambda().eq(BiIndexType::getIsDefault, biIndexTypeParam.getIsDefault());
            }

        }
        List<BiIndexType> list = this.list(queryWrapper);
        Set<Long> pids = new HashSet<>();
        for (BiIndexType biIndexType : list) {
                pids.add(biIndexType.getPid());
                pids.add(biIndexType.getId());
        }
        List<Long> ids = new ArrayList<>();
        ids.addAll(pids);
        List<BiIndexType> byIds = this.findByIds(ids);
        for (BiIndexType byId : byIds) {
            byId.setIsCommonFT("Y".equals(byId.getIsCommon()) ?  true : false);
            byId.setIsDefaultFT("Y".equals(byId.getIsDefault()) ?  true : false);
        }
    return new TreeBuildFactory<BiIndexType>().doTreeBuild(byIds);
    }

    @Override
    public List<TypeBaseTreeNode> selectTree() {
        List<TypeBaseTreeNode> typeBaseTreeNodes = CollectionUtil.newArrayList();
        List<BiIndexType> list = this.list();
        for (BiIndexType biIndexType : list) {
            TypeBaseTreeNode typeBaseTreeNode = new TypeBaseTreeNode();
            typeBaseTreeNode.setId(biIndexType.getId());
            typeBaseTreeNode.setParentId(biIndexType.getPid());
            typeBaseTreeNode.setValue(String.valueOf(biIndexType.getId()));
            typeBaseTreeNode.setTitle(biIndexType.getName());
            typeBaseTreeNode.setWeight(biIndexType.getOrderList());
            typeBaseTreeNodes.add(typeBaseTreeNode);
        }
        return new TreeBuildFactory<TypeBaseTreeNode>().doTreeBuild(typeBaseTreeNodes);
    }

    @Override
    public void upload(MultipartFile file) throws IOException {
        InputStream inputStream = file.getInputStream();
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"GBK");
        Reader reader = new BufferedReader(inputStreamReader);
//        csv解析文件
        CSVParser parse = CSVFormat.EXCEL.parse(reader);
        List<CSVRecord> records = parse.getRecords();
        for (int i = 1; i < parse.getCurrentLineNumber(); i++) {
            BiIndexType biIndexType=new BiIndexType();
            biIndexType.setName(records.get(i).get(0));
            biIndexType.setType(records.get(i).get(1));
            biIndexType.setPid(Long.parseLong(records.get(i).get(2)));
            biIndexType.setIsEnable("1".equals(records.get(i).get(3)));
            biIndexType.setDescription(records.get(i).get(4));

            BiIndexTypeParam biIndexTypeParam=new BiIndexTypeParam();
            BeanUtils.copyProperties(biIndexType,biIndexTypeParam);
            this.add(biIndexTypeParam);
        }
        parse.close();
        reader.close();
    }

    @Override
    public void updateisEnable(BiIndexTypeParam biIndexTypeParam) {
        BiIndexType biIndexType = this.getById(biIndexTypeParam.getId());
        biIndexType.setIsEnable(biIndexTypeParam.getIsEnable());
        this.updateById(biIndexType);
    }

    @Override
    public void updateMaxMinValue(BiIndexType entity) {
        CurrentDataSourceContext.setDataSourceType(WdAnalysisConst.CLICKHOUSE_DATASOURCE);
        BiIndexDataParam dataParam = new BiIndexDataParam();
        dataParam.setTypeId(entity.getId());
        //最大值、最小值
        BigDecimal max = biIndexDataMapper.queryGridMaxValue(dataParam);
        BigDecimal min = biIndexDataMapper.queryGridMinValue(dataParam);
        CurrentDataSourceContext.clearDataSourceType();
        if(max == null){
            max = BigDecimal.ZERO;
            min = BigDecimal.ZERO;
        }
        entity.setMaxValue(max);
        entity.setMinValue(min);
        this.updateById(entity);
    }

    @Override
    public List<BiIndexType> findByParentId(Long parentId) {
        LambdaQueryWrapper<BiIndexType> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BiIndexType::getPid, parentId);
        return this.getBaseMapper().selectList(wrapper);
    }
}
